// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <memory>
#include <string>
#include <vector>

#include "coin2/exchange/base/order/order.h"

#include "coin2/exchange/korbit/api_util/auth_key.h"
#include "coin2/exchange/order/korbit.pb.h"

class KorbitNativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using RestParams = coin2::exchange::order::KorbitRestParams;
  using ActionType = coin2::exchange::base::order::NativePrivateClient::ActionType;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);

 public:
  explicit KorbitNativePrivateClient(
      const MarketExchangeApi& mea,
      const OrderConnectionConfig& config);

  std::shared_ptr<AsioHttpContext> QueryToken();
  std::shared_ptr<AsioHttpContext> QueryAccountBalance();
  std::shared_ptr<AsioHttpContext> QueryOpenOrders(const RestParams& params);
  std::shared_ptr<AsioHttpContext> QueryAllOrders(const RestParams& params);
  std::shared_ptr<AsioHttpContext> QueryTrades(const RestParams& params);
  std::shared_ptr<AsioHttpContext> PlaceOrder(const RestParams& params);
  std::shared_ptr<AsioHttpContext> CancelOrder(const RestParams& params);

  std::shared_ptr<AsioHttpContext> PlaceOrderNorm(const OrderExecution&) override;
  std::shared_ptr<AsioHttpContext> CancelOrderNorm(const OrderExecution&) override;

  RestParams GetRestOrderParams(const OrderSpec& order_spec, int64_t proc_order_id);
  RestParams GetRestCancelParams(const IOrderContext& order_context);

  void SetAuthToken(const std::string& channel, void* data) {
    std::vector<std::string> out = Split(*(static_cast<std::string*>(data)), "\n");
    auth_token_ = out[0];
    LOG(INFO) << "Set auth token!!!!!!!!! " << auth_token_;
    dynamic_cast<KorbitBaseAuth*>(auths_.GetFirst())->auth_token_ = auth_token_;
    dynamic_cast<KorbitBaseAuth*>(auths_.GetFirst())->refresh_token_ = out[1];
  }
  bool has_auth_token() const { return !auth_token_.empty(); }

 protected:
  std::string auth_token_;
};
